classdef MultiLabelKNearestNeighbor ...
        < MultiLabelAlgorithm ...
        & MultiLabelMetricable ...
        & Modelable
    %MULTILABELKNEARESTNEIGHBOR Summary of this class goes here
    %   Detailed explanation goes here
    
    properties
        nK = 10
        smoothing = 1 % Laplace smoothing
    end
    
    methods
        function [ this ] = MultiLabelKNearestNeighbor( name, nK, smoothing )
            if nargin == 0
                this.setName('mlknn');
            end
            if nargin >= 1
                this.setName(name);
            end
            if nargin >= 2
                this.setNK(nK);
            end
            if nargin >= 3
                this.setSmoothing(smoothing);
            end
        end
    end
    
    methods
        function [  ] = setNK( this, nK )
            if nargin == 1
                this.nK = 10;
            end
            if nargin == 2
                this.nK = nK;
            end
        end
        
        function [  ] = setSmoothing( this, smoothing )
            if nargin == 1
                this.smoothing = 1;
            end
            if nargin == 2
                this.smoothing = smoothing;
            end
        end
    end
    
    methods
        function [  ] = build( this, X1, Y1 )
            [this.model.prior, this.model.priorN, ...
                this.model.cond, this.model.condN] ...
                = buildMLKNN(X1, Y1, this.nK, this.smoothing);
            this.model.X1 = X1;
            this.model.Y1 = Y1;
        end
        
        function [ result ] = apply( this, X2, Y2 )
            [result.Y_hat, result.Y_out] = applyMLKNN(this.model.X1, this.model.Y1, ...
                X2, Y2, this.nK, ...
                this.model.prior, this.model.priorN, ...
                this.model.cond, this.model.condN);
        end
    end
    
end

